package com.desaysv.hicar.IProxy;

import android.util.Log;

import com.desaysv.hicar.IProxy.proxy.IProxyInstance;

import java.lang.reflect.Constructor;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author linzi
 * @date 2022-7-18
 */
public class ProxyFactory {
    private ConcurrentHashMap<Class,Object> PROXY_POOL=new ConcurrentHashMap<>();
    private static ProxyFactory mInstance;
    private static final String TAG=ProxyFactory.class.getName();
    private ProxyFactory(){
        Log.e("=====>","初始化");
    }

    private static class test2{
        public static ProxyFactory outInstance=new ProxyFactory();
    }

    public static ProxyFactory getFactory() {
        if(mInstance==null){
            synchronized (ProxyFactory.class){
                if(mInstance==null){
                    mInstance=new ProxyFactory();
                }
            }
        }
        return mInstance;
    }

    public <T extends IProxyInstance>T getProxy(Class<T> t){
        Object temp=PROXY_POOL.get(t);
        if(temp==null) {
            synchronized (ProxyFactory.class) {
                temp = PROXY_POOL.get(t);
                //公共构造函数
                if (temp == null) {
                    try{
                        IProxyInstance iproxy =  t.newInstance();
//                        Object tProxy = Proxy.newProxyInstance(t.getClassLoader(), t.getInterfaces(), (Object pxy, Method method, Object[] args) -> method.invoke(iproxy, args));
                        temp=iproxy.getInstance();
                        PROXY_POOL.put(t,temp);
                    }catch (Exception e){
                        Log.e(TAG,"public method init fail!!!");
                    }
                }
                //私有构造函数
                if (temp == null) {
                    try{
                        Constructor<?>[] conns=t.getDeclaredConstructors();
                        IProxyInstance iproxy = null;
                        for (Constructor<?> conn : conns) {
                            try{
                                conn.setAccessible(true);
                                iproxy = (IProxyInstance) conn.newInstance();
                                if(iproxy!=null){
                                    break;
                                }
                            }catch (Exception e){
                                Log.e(TAG,"private method init fail!!!");
                            }
                        }
//                        IProxyInstance finalIproxy = iproxy;
//                        Object tProxy = Proxy.newProxyInstance(t.getClassLoader(), t.getInterfaces(), (Object pxy, Method method, Object[] args) -> method.invoke(finalIproxy, args));
                        temp=(iproxy).getInstance();
                        PROXY_POOL.put(t,temp);
                    }catch (Exception e){
                        Log.e(TAG,"init fail!!!");
                    }
                }
            }
        }
        return (T) temp;
    }

    public <T extends IProxyInstance>boolean checkInit(Class<T> t){
        return PROXY_POOL.get(t)!=null;
    }
}
